#include "render_pin.h"
#include "qbe/src/layout/layout.hpp"
#include "qlib/utils/font.h"

namespace qbe::utils::TempRender {

RenderPin::RenderPin(vsg::ref_ptr<vsg::Options> options, std::vector<qlib::Pin::s_ptr> pins) : m_pins(pins) {
  switchObject = vsg::Switch::create();
  transform = vsg::MatrixTransform::create();
  switchObject->addChild(true, transform);

  std::vector<Mesh2D> meshs;
  for (auto i : m_pins) {
    auto lines = qlib::get_text(i->text, i->origin, i->fontSize, i->rotation, i->anchor);
    auto mesh = Mesh2D();
    auto vertices = vsg::vec2Array::create(lines.size());
    auto indices = vsg::uintArray::create(lines.size());
    for (uint32_t i = 0; i < lines.size(); i++) {
      (*vertices)[i] = {float(lines[i].x), float(lines[i].y)};
      (*indices)[i] = i;
    }
    mesh.vertices = vertices;
    mesh.indices = indices;
    meshs.push_back(mesh);
    meshs.push_back(mesh);
  }
  Mesh2D merge_result;
  mesh_merge(meshs, merge_result);
  LineShaderMaterial2D material{Line_Uniform{vsg::vec4(1.0, 0.0, 0.0, 1.0), vsg::vec2(1316.0, 847.0), 100.0, 70.0, true},
                                "shaders/cell/line.vert.spv", "shaders/cell/line.frag.spv"};

  line_node = LineMeshNode::create(options, qlib::Tag{0, 0}, merge_result, material, VkPrimitiveTopology::VK_PRIMITIVE_TOPOLOGY_LINE_LIST);
  transform->addChild(line_node);


  Mesh2D point_merge_result;
  point_merge_result.vertices = vsg::vec2Array::create(m_pins.size());
  point_merge_result.indices = vsg::uintArray::create(m_pins.size());
  for (uint32_t i = 0; i < m_pins.size(); i++) {
    (*point_merge_result.vertices)[i] = vsg::vec2{float(m_pins[i]->origin.x), float(m_pins[i]->origin.y)};
    (*point_merge_result.indices)[i] = i;
  }
  PointShaderMaterial2D point_material{Point_Uniform{vsg::vec4(1.0, 0.0, 0.0, 1.0), 2, 20},
                                "shaders/cell/key_point.vert.spv", "shaders/cell/key_point.frag.spv"};

  point_node =
      PointMeshNode::create(options, point_merge_result, point_material, VkPrimitiveTopology::VK_PRIMITIVE_TOPOLOGY_POINT_LIST);
  transform->addChild(point_node);
}

RenderPin ::~RenderPin() {}


void RenderPin::updateData(std::vector<qlib::Pin::s_ptr> pins) {
  if (pins.empty())
    return;
  m_pins = pins;
  std::vector<Mesh2D> meshs;
  for (auto i : m_pins) {
    vsg::dvec4 origin(i->origin.x, i->origin.y, 0.0, 1.0);
    origin = m * origin;
    auto lines = qlib::get_text(i->text, qlib::Vec2d(origin.x, origin.y + 20), 20, 0, qlib::Anchor::S);
    auto mesh = Mesh2D();
    auto vertices = vsg::vec2Array::create(lines.size());
    auto indices = vsg::uintArray::create(lines.size());
    for (uint32_t i = 0; i < lines.size(); i++) {
      (*vertices)[i] = {float(lines[i].x), float(lines[i].y)};
      (*indices)[i] = i;
    }
    mesh.vertices = vertices;
    mesh.indices = indices;
    meshs.push_back(mesh);
    meshs.push_back(mesh);
  }
  Mesh2D merge_result;
  mesh_merge(meshs, merge_result);
  line_node->mesh = merge_result;
  line_node->update();

  Mesh2D point_merge_result;
  point_merge_result.vertices = vsg::vec2Array::create(m_pins.size());
  point_merge_result.indices = vsg::uintArray::create(m_pins.size());
  for (uint32_t i = 0; i < m_pins.size(); i++) {
    vsg::dvec4 origin(m_pins[i]->origin.x, m_pins[i]->origin.y, 0.0, 1.0);
    origin = m * origin;
    (*point_merge_result.vertices)[i] = vsg::vec2{float(origin.x), float(origin.y)};
    (*point_merge_result.indices)[i] = i;
  }
  point_node->mesh = point_merge_result;
  point_node->update();
}

void RenderPin::setShowHide(bool is_show) {
  switchObject->setAllChildren(is_show);
}

}  // namespace qbe::utils::TempRender